/* api */
import { taskSubscribe, taskUnSubscribe } from '@src/api/TaskApi'
/* enum */
import ComponentNameEnum from '@model/enum/ComponentNameEnum'
import SubscriptionModuleEnum from '@model/enum/SubscriptionModuleEnum'
/* model */
import { getTaskSubscribeResult, getTaskUnSubscribeResult } from '@model/param/out/Task'
import { TaskSubscriceModel } from '@model/param/in/Task'
/* vue */
import VC from '@model/VC'
import { Component, Emit, Prop, Ref, Watch } from 'vue-property-decorator'
import { CreateElement, VNode } from 'vue'
/* util */
import Log from '@src/util/log.ts'
import Platform from '@src/util/platform'
/* scss */
import '@src/component/business/BizListView/components/SubscriptionButton/SubscriptionButton.scss'
import { t } from '@src/locales'

type SubscriptionActionPromise = (params: TaskSubscriceModel) => Promise<getTaskSubscribeResult | getTaskUnSubscribeResult>

enum SubscriptionButtonWatchPropertyEnum {
  Subscribed = 'subscribed'
}

enum SubscriptionButtonEmitEventNameEnum {
  Change = 'change'
}

@Component({ 
  name: ComponentNameEnum.SubscriptionButton,
})
export default class SubscriptionButton extends VC {
  
  /* 订阅的模块名称 */
  @Prop() readonly module: SubscriptionModuleEnum | undefined
  /* 提示内容 */
  @Prop() readonly tooltipContent: string | undefined
  /* 已订阅状态 */
  @Prop() readonly subscribed: boolean | undefined
  
  /* 是否为订阅状态 */
  private isSubscribe: boolean = false
  /* 等待状态 */
  private pending: boolean = false
  
  /**
   * @description: 订阅状态变化事件
   * @param {boolean} newValue 订阅状态的新值
   * @return {void}
   */
  @Watch(SubscriptionButtonWatchPropertyEnum.Subscribed, { immediate: true, deep: true })
  onSubscribedChangedHandler(newValue: boolean): void {
    this.isSubscribe = newValue
  }
  
  @Emit(SubscriptionButtonEmitEventNameEnum.Change)
  emitSubscribeChangedHandler(isSubscribed: boolean): boolean {
    return isSubscribed
  }
  
  /**
   * @description: 切换订阅状态
   * @param {Boolean} toggle 订阅状态
   * @return {Promise<void>}
   */  
  private async toggleSubscribe(): Promise<void | boolean> {
    if (this.pending) {
      return Log.warn('Caused: is pending ', this.toggleSubscribe.name)
    }
    
    // 没有模块参数则提示
    if (!this.module) {
      return Log.warn('Caused: SubscriptionButton property module is empty', this.toggleSubscribe.name)
    }
    
    this.pending = true
    const subscriptionActionPromise: SubscriptionActionPromise = this.isSubscribe ? taskUnSubscribe : taskSubscribe;
    
    try {
      let result = await subscriptionActionPromise({ module: this.module })
      if (!result.succ) {
        return Platform.alert(result.message)
      }
      
      const tipText = this.isSubscribe ? t('common.base.tip.canceledSubscribeNotify') : t('common.base.tip.subscribeNotify')
      Platform.alert(tipText)
      
      this.isSubscribe = !this.isSubscribe
      
      this.emitSubscribeChangedHandler(this.isSubscribe)
      
    } catch (error) {
      Log.error(error, this.toggleSubscribe.name)
    } finally {
      this.pending = false
    }
    
  }
  
  /**
   * @description: 渲染订阅按钮
   * @return {VNode}
   */  
  private renderSubscriptionButton(): VNode {
    const classNames: string[] = [
      'pointer',
      this.isSubscribe ? `${ComponentNameEnum.SubscriptionButton}__actived` : ''
    ]
    
    return (
      <div class={classNames} onClick={() => this.toggleSubscribe()}>
        <i class='iconfont task-icon icon-ding-yue ml_12'>
        </i>
        { this.isSubscribe ? t('common.base.subscribed'): t('common.base.notSubscribed') }
      </div>
    )
  }
  
  /**
   * @description: 渲染主要内容容器
   * @return {VNode}
   */  
  renderContentContainer() {
    // 无提示内容则不渲染提示标签
    if (!this.tooltipContent) {
      return this.renderSubscriptionButton()
    }
    
    return (
      <el-tooltip effect='dark' content={this.tooltipContent} placement='top'>
        { this.renderSubscriptionButton() }
      </el-tooltip>
    )
  }
  
  render(h: CreateElement) {
    return (
      <div class={ComponentNameEnum.SubscriptionButton}>
        { this.renderContentContainer() }
      </div>
    )
  }
}

